package com.dt.platform.hr.service.impl;

import javax.annotation.Resource;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dt.platform.constants.enums.hr.PaperQuestionModeEnum;
import com.dt.platform.constants.enums.hr.PaperQuestionTypeEnum;
import com.dt.platform.constants.enums.hr.PaperTaskResultStatusEnum;
import com.dt.platform.constants.enums.hr.PaperTaskStatusEnum;
import com.dt.platform.domain.hr.*;
import com.dt.platform.domain.hr.meta.PaperMeta;
import com.dt.platform.domain.hr.meta.PaperQuestionRelMeta;
import com.dt.platform.domain.hr.meta.PaperTaskMeta;
import com.dt.platform.hr.service.*;
import com.github.foxnic.commons.bean.BeanUtil;
import com.github.foxnic.commons.lang.StringUtil;
import com.github.foxnic.commons.log.Logger;
import com.github.foxnic.dao.data.Rcd;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.foxnic.dao.entity.ReferCause;
import com.github.foxnic.commons.collection.MapUtil;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;


import com.github.foxnic.api.transter.Result;
import com.github.foxnic.dao.data.PagedList;
import com.github.foxnic.dao.entity.SuperService;
import com.github.foxnic.dao.spec.DAO;
import java.lang.reflect.Field;
import com.github.foxnic.commons.busi.id.IDGenerator;
import com.github.foxnic.sql.expr.ConditionExpr;
import com.github.foxnic.api.error.ErrorDesc;
import com.github.foxnic.dao.excel.ExcelWriter;
import com.github.foxnic.dao.excel.ValidateResult;
import com.github.foxnic.dao.excel.ExcelStructure;
import java.io.InputStream;
import com.github.foxnic.sql.meta.DBField;
import com.github.foxnic.dao.data.SaveMode;
import com.github.foxnic.dao.meta.DBColumnMeta;
import com.github.foxnic.sql.expr.Select;

import org.github.foxnic.web.framework.dao.DBConfigs;

/**
 * <p>
 * 考试试卷服务实现
 * </p>
 * @author 金杰 , maillank@qq.com
 * @since 2024-09-14 11:41:34
*/


@Service("HrPaperService")

public class PaperServiceImpl extends SuperService<Paper> implements IPaperService {

	@Autowired
	private IPaperQuestionRelService paperQuestionRelService;

	@Autowired
	private IPaperReleaseService paperReleaseService;

	@Autowired
	private IPaperTaskService paperTaskService;

	@Autowired
	private IPaperQuestionAnswerService paperQuestionAnswerService;

	/**
	 * 注入DAO对象
	 * */
	@Resource(name=DBConfigs.PRIMARY_DAO) 
	private DAO dao=null;

	/**
	 * 获得 DAO 对象
	 * */
	public DAO dao() { return dao; }



	@Override
	public Object generateId(Field field) {
		return IDGenerator.getSnowflakeIdString();
	}



	private Result renderQuestionContent(String id){
		Paper paper=this.getById(id);
		dao.fill(paper).with(PaperMeta.PAPER_QUESTION_REAL_LIST).execute();
		List<PaperQuestionRel> relList=paper.getPaperQuestionRealList();
		dao.fill(relList).with(PaperQuestionRelMeta.PAPER_QUESTION_ITEM_LIST).execute();
		if(relList.size()>0){
			for(int i=0;i<relList.size();i++){
				PaperQuestionRel rel=relList.get(i);
				List<PaperQuestionItem> itemList=rel.getPaperQuestionItemList();
				JSONArray data=new JSONArray();
				JSONArray rightData=new JSONArray();
				for(int j=0;j<itemList.size();j++){
					JSONObject obj=new JSONObject();
					obj.put("id",itemList.get(j).getId());
					obj.put("code",itemList.get(j).getCode());
					obj.put("item",itemList.get(j).getContent());
					if("right".equals(itemList.get(j).getSelected())){
						JSONObject rightObj=new JSONObject();
						rightObj.put("id",itemList.get(j).getId());
						rightObj.put("code",itemList.get(j).getCode());
						rightData.add(rightObj);
					}
					data.add(obj);
				}
			 dao.execute("update hr_paper_question_rel set item_answer_text_right=?, item_text =? where id=?",rightData.toJSONString(),data.toJSONString(),rel.getId());
			}
		}
		return ErrorDesc.success();

	}


	/**
	 * 添加，根据 throwsException 参数抛出异常或返回 Result 对象
	 *
	 * @param paper  数据对象
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 结果 , 如果失败返回 false，成功返回 true
	 */

	@Override
	public Result insert(Paper paper,boolean throwsException) {
		Result r=super.insert(paper,throwsException);

		if(r.isSuccess()){
			dao.execute("update hr_paper_question_rel set paper_id=? where paper_id=?",paper.getId(),paper.getSelectedCode());
			renderQuestionContent(paper.getId());
			computeQuestionStatics(paper);
		}
		renderQuestionContent(paper.getId());
		return r;
	}

	private  List createRandomList(List list, int n) {
		// TODO Auto-generated method stub
		Map map = new HashMap();
		List listNew = new ArrayList();
		if (list.size() <= n) {
			return list;
		} else {
			while (map.size() < n) {
				int random = (int) (Math.random() * list.size());
				if (!map.containsKey(random)) {
					map.put(random, "");
					listNew.add(list.get(random));
				}
			}
			return listNew;
		}
	}

	@Override
	public Result createPaper(String paperId){

		Paper paper=this.getById(paperId);
		this.computeQuestionStatics(paper);
		dao.fill(paper).with(PaperMeta.PAPER_QUESTION_REAL_LIST).execute();
		List<PaperQuestionRel> sourceQuestionList=paper.getPaperQuestionRealList();
		String afterPaperId="";
		String sourcePaperId=paper.getId();
		paper.setOwnerCode(paper.getQuestionMode());
		paper.setOwnerId(sourcePaperId);
		paper.setId(null);
		Result paperRes=this.insert(paper,false);
		if(!paperRes.isSuccess()){
			return paperRes;
		}else{
			afterPaperId=paper.getId();
		}
		if(PaperQuestionModeEnum.RAND.code().equals(paper.getQuestionMode())){
			paper=this.getById(afterPaperId);
			dao.fill(paper)
					.with(PaperMeta.PAPER_QUESTION_FOR_CHOICE_LIST)
					.with(PaperMeta.PAPER_QUESTION_FOR_JUDGE_LIST)
					.with(PaperMeta.PAPER_QUESTION_FOR_RADIO_LIST)
					.with(PaperMeta.PAPER_QUESTION_FOR_TEXT_AREA_LIST)
					.execute();
			List<PaperQuestion> judgeList=paper.getPaperQuestionForJudgeList();
			Collections.shuffle(judgeList);
			List<PaperQuestion> radioList=paper.getPaperQuestionForRadioList();
			Collections.shuffle(radioList);
			List<PaperQuestion> choiceList=paper.getPaperQuestionForChoiceList();
			Collections.shuffle(choiceList);
			List<PaperQuestion> textAreaList=paper.getPaperQuestionForTextAreaList();
			Collections.shuffle(textAreaList);
			if(paper.getRadioRCnt()>radioList.size()){
				return ErrorDesc.failureMessage("题库中没有足够的"+PaperQuestionTypeEnum.RADIO.text()+",需求数量:"+paper.getRadioRCnt()+"题,题库中数量"+radioList.size()+"题。");
			}else{
				List<PaperQuestion> radioListRand=createRandomList(radioList,paper.getRadioRCnt());
				for(int i=0;i<paper.getRadioRCnt();i++){
					PaperQuestion question=radioListRand.get(i);
					PaperQuestionRel rel=new PaperQuestionRel();
					rel.setQuestionId(question.getId());
					rel.setQuestionName(question.getName());
					rel.setQuestionLevel(question.getQuestionLevel());
					rel.setQuestionAnalysis(question.getQuestionAnalysis());
					rel.setQuestionName(question.getName());
					rel.setQuestionImageId(question.getImageId());
					rel.setQuestionFileId(question.getFileId());
					rel.setQuestionType(question.getQuestionType());
					rel.setPaperId(afterPaperId);
					rel.setScore(paper.getRadioScore());
					paperQuestionRelService.insert(rel,false);
				}
			}
			if(paper.getJudgeRCnt()>judgeList.size()){
				return ErrorDesc.failureMessage("题库中没有足够的"+PaperQuestionTypeEnum.JUDGE.text()+",需求数量:"+paper.getRadioRCnt()+"题,题库中数量"+judgeList.size()+"题。");
			}else{
				List<PaperQuestion> judgeListRand=createRandomList(judgeList,paper.getJudgeRCnt());
				for(int i=0;i<paper.getJudgeRCnt();i++){
					PaperQuestion question=judgeListRand.get(i);
					PaperQuestionRel rel=new PaperQuestionRel();
					rel.setQuestionId(question.getId());
					rel.setQuestionName(question.getName());
					rel.setQuestionImageId(question.getImageId());
					rel.setQuestionFileId(question.getFileId());
					rel.setQuestionLevel(question.getQuestionLevel());
					rel.setQuestionAnalysis(question.getQuestionAnalysis());
					rel.setQuestionType(question.getQuestionType());
					rel.setPaperId(afterPaperId);
					rel.setScore(paper.getRadioScore());
					paperQuestionRelService.insert(rel,false);
				}
			}
			if(paper.getChoiceRCnt()>choiceList.size()){
				return ErrorDesc.failureMessage("题库中没有足够的"+PaperQuestionTypeEnum.CHOICE.text()+",需求数量:"+paper.getRadioRCnt()+"题,题库中数量"+choiceList.size()+"题。");
			}else{
				List<PaperQuestion> choiceListRand=createRandomList(choiceList,paper.getChoiceRCnt());
				for(int i=0;i<paper.getChoiceRCnt();i++){
					PaperQuestion question=choiceListRand.get(i);
					PaperQuestionRel rel=new PaperQuestionRel();
					rel.setQuestionId(question.getId());
					rel.setQuestionName(question.getName());
					rel.setQuestionImageId(question.getImageId());
					rel.setQuestionLevel(question.getQuestionLevel());
					rel.setQuestionAnalysis(question.getQuestionAnalysis());
					rel.setQuestionFileId(question.getFileId());
					rel.setQuestionType(question.getQuestionType());
					rel.setPaperId(afterPaperId);
					rel.setScore(paper.getRadioScore());
					paperQuestionRelService.insert(rel,false);
				}
			}
			if(paper.getTextareaRCnt()>textAreaList.size()){
				return ErrorDesc.failureMessage("题库中没有足够的填空题,需求数量:"+paper.getTextareaRCnt()+"题,题库中数量"+textAreaList.size()+"题。");
			}else{
				List<PaperQuestion> textAreaListRand=createRandomList(textAreaList,paper.getTextareaRCnt());
				for(int i=0;i<paper.getTextareaRCnt();i++){
					PaperQuestion question=textAreaListRand.get(i);
					PaperQuestionRel rel=new PaperQuestionRel();
					rel.setQuestionId(question.getId());
					rel.setQuestionAnalysis(question.getQuestionAnalysis());
					rel.setQuestionLevel(question.getQuestionLevel());
					rel.setQuestionAnalysis(question.getQuestionAnalysis());
					rel.setQuestionName(question.getName());
					rel.setQuestionImageId(question.getImageId());
					rel.setQuestionFileId(question.getFileId());
					rel.setQuestionType(question.getQuestionType());
					rel.setPaperId(afterPaperId);
					rel.setScore(paper.getRadioScore());
					paperQuestionRelService.insert(rel,false);
				}
			}
		}else if(PaperQuestionModeEnum.FIX.code().equals(paper.getQuestionMode())){
			for(int i=0;i<sourceQuestionList.size();i++){
				PaperQuestionRel rel=sourceQuestionList.get(i);
				rel.setId(null);
				rel.setPaperId(afterPaperId);
				paperQuestionRelService.insert(rel,false);
			}
		}else{
			return ErrorDesc.failureMessage("当前模式不支持!");
		}
		renderQuestionContent(afterPaperId);
		JSONObject res=new JSONObject();
		res.put("id",afterPaperId);
		Logger.info("生成试卷成功,ID:"+afterPaperId);


		Result<JSONObject> lst=new Result<JSONObject>();
		lst.success();
		lst.data(res);
		return lst;
	}

	//id 必须传
	@Override
	public Result getPaper(String id,String taskId) {

		Paper paper=this.getById(id);
		//抽屉模式
		if(StringUtil.isBlank(taskId)){
			//如果是任务单过来，不需要生成试卷，任务单已生成动态试卷
			if(PaperQuestionModeEnum.RAND.code().equals(paper.getQuestionMode())){
				Result createPaperRes=this.createPaper(id);
				if(createPaperRes.isSuccess()){
					JSONObject obj= (JSONObject)createPaperRes.getData();
					paper=this.getById(obj.getString("id"));
				}else{
					return createPaperRes;
				}
			}
		}
		dao.fill(paper).with(PaperMeta.PAPER_QUESTION_REAL_LIST).execute();
		List<PaperQuestionRel> questionList=paper.getPaperQuestionRealList();
		JSONArray radioData = new JSONArray();
		JSONArray choiceData = new JSONArray();
		JSONArray judgeData = new JSONArray();
		JSONArray textAreaData = new JSONArray();
		for(int i=0;i<questionList.size();i++) {
			PaperQuestionRel question = questionList.get(i);
			JSONObject obj=new JSONObject();
			obj.put("id",question.getId());
			obj.put("questionId",question.getQuestionId());
			obj.put("questionType",question.getQuestionType());
			if(StringUtil.isBlank(taskId)){
				obj.put("isAnswer","no");
				obj.put("isRight","");
			}else{
				Rcd rs=dao.queryRecord("select * from hr_paper_question_answer where question_rel_id=? and task_id=?",question.getId(),taskId);
				if(rs==null){
					obj.put("isAnswer","no");
					obj.put("isRight","");
				}else{
					if(StringUtil.isBlank(rs.getString("value"))
							||"[]".equals(rs.getString("value")) ||"{}".equals(rs.getString("value"))
					){
						obj.put("isAnswer","no");
					}else{
						obj.put("isAnswer","yes");
					}
					if(StringUtil.isBlank(rs.getString("is_right"))){
						obj.put("isRight","");
					}else{
						obj.put("isRight",rs.getString("is_right"));
					}
				}
			}
			if(PaperQuestionTypeEnum.JUDGE.code().equals(question.getQuestionType())){
				judgeData.add(obj);
			}else if(PaperQuestionTypeEnum.RADIO.code().equals(question.getQuestionType())){
				radioData.add(obj);
			}else if(PaperQuestionTypeEnum.CHOICE.code().equals(question.getQuestionType())){
				choiceData.add(obj);
			}else if(PaperQuestionTypeEnum.TEXTAREA.code().equals(question.getQuestionType())){
				textAreaData.add(obj);
			}
		}
		int num=0;
		JSONObject data=new JSONObject();
		JSONArray questList=new JSONArray();
		JSONArray question = new JSONArray();
		if(judgeData.size()>0){
			questList.add("judge");
			for(int i=0;i<judgeData.size();i++){
				num++;
				judgeData.getJSONObject(i).put("questionNumber",num);
				question.add(judgeData.getJSONObject(i));
			}
			data.put("judge",judgeData);
		}
		if(radioData.size()>0){
			questList.add("radio");
			for(int i=0;i<radioData.size();i++){
				num++;
				radioData.getJSONObject(i).put("questionNumber",num);
				question.add(radioData.getJSONObject(i));
			}
			data.put("radio",radioData);
		}
		if(choiceData.size()>0){
			questList.add("choice");
			for(int i=0;i<choiceData.size();i++){
				num++;
				choiceData.getJSONObject(i).put("questionNumber",num);
				question.add(choiceData.getJSONObject(i));
			}
			data.put("choice",choiceData);
		}
		if(textAreaData.size()>0){
			questList.add("textarea");
			for(int i=0;i<textAreaData.size();i++){
				num++;
				textAreaData.getJSONObject(i).put("questionNumber",num);
				question.add(textAreaData.getJSONObject(i));
			}
			data.put("textarea",textAreaData);
		}
		data.put("paperName",paper.getName());
		data.put("paperCost",paper.getCost());
		data.put("paperTotalScore",paper.getTotalScore());
		data.put("questionType",questList);
		data.put("questionList",question);


		Result<JSONObject> lst=new Result<JSONObject>();
		lst.success();
		lst.data(data);
		return lst;

	}


	@Override
	public Result getPaperQuestion(String id,String taskId) {
		PaperQuestionRel question=paperQuestionRelService.getById(id);
		if(question==null){
			return ErrorDesc.failureMessage("没找到题目");
		}
		dao.fill(question).with(PaperQuestionRelMeta.LEVEL_DICT).execute();
		JSONObject obj = new JSONObject();
		obj.put("id",question.getId());
		obj.put("learnPaperId",question.getLearnPaperId());
		obj.put("questionType",question.getQuestionType());
		obj.put("questionName",question.getQuestionName());
		obj.put("questionFileId",question.getQuestionFileId());
		obj.put("questionImageId",question.getQuestionImageId());
		obj.put("questionScore",question.getScore());
		obj.put("questionId",question.getQuestionId());
		obj.put("questionLevel",question.getQuestionLevel());
		obj.put("questionLevelName",question.getLevelDict()!=null ? question.getLevelDict().getLabel():"");
		obj.put("itemText",question.getItemText());
		obj.put("answerData","[]");
		obj.put("questionAnalysis",question.getQuestionAnalysis());
		obj.put("itemAnswerTextRight","[]");
		if(StringUtil.isBlank(taskId)){
			obj.put("isAnswer","no");
			obj.put("isRight","");
			obj.put("questionAnalysis",question.getQuestionAnalysis());
			obj.put("itemAnswerTextRight",question.getItemAnswerTextRight());
		}else{
			PaperTask paperTask=paperTaskService.getById(taskId);
			if(PaperTaskResultStatusEnum.PASS.code().equals(paperTask.getPaperStatus())
			||PaperTaskResultStatusEnum.ACTED.code().equals(paperTask.getPaperStatus())
			||PaperTaskResultStatusEnum.FAIL.code().equals(paperTask.getPaperStatus())){
				obj.put("questionAnalysis",question.getQuestionAnalysis());
				obj.put("itemAnswerTextRight",question.getItemAnswerTextRight());
			}else{
				obj.put("questionAnalysis","");
				obj.put("itemAnswerTextRight","[]");
			}


			Rcd rs=dao.queryRecord("select * from hr_paper_question_answer where question_rel_id=? and task_id=?",question.getId(),taskId);
			if(rs==null){
				obj.put("isAnswer","no");
				obj.put("isRight","");
			}else{
				obj.put("answerData",rs.getString("value"));
				if(StringUtil.isBlank(rs.getString("value"))
				||"[]".equals(rs.getString("value")) ||"{}".equals(rs.getString("value"))
				){
					obj.put("isAnswer","no");
				}else{
					obj.put("isAnswer","yes");
				}
				if(StringUtil.isBlank(rs.getString("is_right"))){
					obj.put("isRight","");
				}else{
					obj.put("isRight",rs.getString("is_right"));
				}
			}
		}
		if(StringUtil.isBlank(obj.getString("answerData"))){
			obj.put("answerData","[]");
		}

		Result<JSONObject> lst=new Result<JSONObject>();
		lst.success();
		lst.data(obj);
		return lst;

	}


	@Override
	public Result evaluatePapers(List<String> ids) {
		if(ids==null||ids.size()==0){
			return ErrorDesc.failureMessage("请选择要批改的试卷");
		}
		for(int i=0;i<ids.size();i++){
			evaluatePaper(ids.get(i));
		}
		return ErrorDesc.success();
	}


	@Override
	public Result evaluatePaper(String taskId) {
		BigDecimal totalScore=new BigDecimal("0");
		PaperTask paperTask=paperTaskService.getById(taskId);
		//答题中，或者已打完，可以进行评分
		if (PaperTaskResultStatusEnum.ACTED.code().equals(paperTask.getPaperStatus())||PaperTaskResultStatusEnum.ACTING.code().equals(paperTask.getPaperStatus())){
			dao.fill(paperTask).with(PaperTaskMeta.PAPER).with(PaperTaskMeta.PAPER_QUESTION_REAL_LIST).execute();
			Paper paper=paperTask.getPaper();

			List<PaperQuestionRel> questionList=paperTask.getPaperQuestionRealList();
			for(int i=0;i<questionList.size();i++){
				PaperQuestionRel question=questionList.get(i);
				String rightAnswerStr=question.getItemAnswerTextRight();
				JSONArray rightAnswerArr=new JSONArray();
				if((!StringUtil.isBlank(rightAnswerStr)) && rightAnswerStr.startsWith("[")){
					rightAnswerArr=JSONArray.parseArray(rightAnswerStr);
				}
				PaperQuestionAnswer paperQuestionAnswerVO=new PaperQuestionAnswer();
				paperQuestionAnswerVO.setTaskId(taskId);
				paperQuestionAnswerVO.setQuestionRelId(question.getId());
				PaperQuestionAnswer answer= paperQuestionAnswerService.queryEntity(paperQuestionAnswerVO);

				if(answer==null){
					PaperQuestionAnswer answerInsert=new PaperQuestionAnswer();
					answerInsert.setTaskId(taskId);
					answerInsert.setQuestionRelId(question.getId());
					answerInsert.setValue("[]");
					answerInsert.setIsRight("no");
					answerInsert.setContent("未答题");
					paperQuestionAnswerService.insert(answerInsert,false);
					continue;
				}

				//单选和判断题
				if(PaperQuestionTypeEnum.JUDGE.code().equals(question.getQuestionType())
						||PaperQuestionTypeEnum.RADIO.code().equals(question.getQuestionType())){
					if(StringUtil.isBlank(answer.getValue())
							||"[]".equals(answer.getValue()) ){
						answer.setIsRight("no");
						answer.setContent("未答题");
						paperQuestionAnswerService.update(answer,SaveMode.NOT_NULL_FIELDS,false);
					}
					JSONArray answerArr=JSONArray.parseArray(answer.getValue());
					if(rightAnswerArr.size()==1
							&& answerArr.size()== rightAnswerArr.size()
							&& answerArr.getString(0).equals(rightAnswerArr.getJSONObject(0).getString("id"))){
						answer.setIsRight("yes");
						totalScore=totalScore.add(question.getScore());
						paperQuestionAnswerService.update(answer,SaveMode.NOT_NULL_FIELDS,false);
					}else{
						answer.setIsRight("no");
						paperQuestionAnswerService.update(answer,SaveMode.NOT_NULL_FIELDS,false);
					}
				}else if(PaperQuestionTypeEnum.CHOICE.code().equals(question.getQuestionType())){
					//多选题
					if(StringUtil.isBlank(answer.getValue())
							||"[]".equals(answer.getValue()) ){
						answer.setIsRight("no");
						answer.setContent("未答题");
						paperQuestionAnswerService.update(answer,SaveMode.NOT_NULL_FIELDS,false);
					}
					JSONArray answerArr=JSONArray.parseArray(answer.getValue());
					if(answerArr.size()==rightAnswerArr.size()&&answerArr.size()>0){
						String isRight="yes";
						for(int j=0;j<rightAnswerArr.size();j++){
							if(!answerArr.contains(rightAnswerArr.getJSONObject(i).getString("id"))){
								isRight="no";
								break;
							}
						}
						if("yes".equals(isRight)){
							totalScore=totalScore.add(question.getScore());
						}
						answer.setIsRight(isRight);
						paperQuestionAnswerService.update(answer,SaveMode.NOT_NULL_FIELDS,false);
					}else{
						answer.setIsRight("no");
						paperQuestionAnswerService.update(answer,SaveMode.NOT_NULL_FIELDS,false);
					}
				}else if(PaperQuestionTypeEnum.TEXTAREA.code().equals(question.getQuestionType())){
					answer.setIsRight("yes");
					paperQuestionAnswerService.update(answer,SaveMode.NOT_NULL_FIELDS,false);
					Logger.info("当前填空题不计入分数");
				}else{
					Logger.info("未知的题目类型:"+question.getQuestionType());
				}
			}

			if(totalScore.compareTo(paper.getPassScore())>-1){
				paperTask.setPaperStatus(PaperTaskResultStatusEnum.PASS.code());
			}else{
				paperTask.setPaperStatus(PaperTaskResultStatusEnum.FAIL.code());
			}
			paperTask.setScore(totalScore);
			paperTaskService.update(paperTask,SaveMode.NOT_NULL_FIELDS,false);

		}else if(PaperTaskResultStatusEnum.NOT_ACT.code().equals(paperTask.getPaperStatus())){
			paperTask.setPaperStatus(PaperTaskResultStatusEnum.FAIL.code());
			paperTask.setScore(totalScore);
			paperTaskService.update(paperTask,SaveMode.NOT_NULL_FIELDS,false);

		}else {
			Logger.info("未知的试卷状态:"+paperTask.getPaperStatus());

		}
		return ErrorDesc.success();

	}


	@Override
	public Result finish(String taskId) {

		PaperTask paperTask=paperTaskService.getById(taskId);
		dao.fill(paperTask).with(PaperTaskMeta.PAPER_RELEASE).execute();
		if(PaperTaskResultStatusEnum.ACTING.code().equals(paperTask.getPaperStatus())){
			//判断当前时间是否到,时间到，直接交卷，
			Date curTime=new Date();
			PaperRelease release=paperTask.getPaperRelease();
			Calendar calendar=Calendar.getInstance();
			calendar.setTime(paperTask.getStartTime());
			calendar.add(Calendar.MINUTE, paperTask.getPaperRelease().getCost());
			Date endTime=calendar.getTime();
			if(curTime.after(release.getEdate())||curTime.after(endTime)){
				paperTask.setPaperStatus(PaperTaskResultStatusEnum.ACTED.code());
				paperTask.setFinishTime(curTime);
				paperTaskService.update(paperTask,SaveMode.NOT_NULL_FIELDS,false);
				evaluatePaper(taskId);
				return ErrorDesc.success().message("答题时间已到，交卷成功");
			}else{
				//时间没到，交卷必须全部答完
				//检查是否答题完成
				Result paperRes=getPaper(paperTask.getPaperId(), taskId);
				JSONObject paperObj= (JSONObject) paperRes.getData();
				JSONArray questionList=paperObj.getJSONArray("questionList");
				for(int i=0;i<questionList.size();i++){
					if( "no".equals(questionList.getJSONObject(i).getString("isAnswer"))){
						return ErrorDesc.failureMessage("有未完成的题目，请全部答完后提交.");
					}
				}
				//答题完成交卷
				paperTask.setPaperStatus(PaperTaskResultStatusEnum.ACTED.code());
				paperTask.setFinishTime(curTime);
				paperTaskService.update(paperTask,SaveMode.NOT_NULL_FIELDS,false);
				evaluatePaper(taskId);
				return ErrorDesc.success().message("全部题目已做完,交卷成功");
			}
		}else{
			return ErrorDesc.failureMessage("当前状态不对，不用重复交卷");
		}

	}

	@Override
	public Result answer(String taskId, String questionRelId,String value) {


		PaperQuestionRel paperQuestionRel= paperQuestionRelService.getById(questionRelId);
		if(PaperQuestionTypeEnum.RADIO.code().equals(paperQuestionRel.getQuestionType())
				||PaperQuestionTypeEnum.JUDGE.code().equals(paperQuestionRel.getQuestionType())){
			JSONArray arr=JSONArray.parseArray(value);
			if(arr.size()>1){
				return ErrorDesc.failureMessage("当前题型只支持单选,请重新选择。");
			}
		}else if(PaperQuestionTypeEnum.CHOICE.code().equals(paperQuestionRel.getQuestionType())){

		}else if(PaperQuestionTypeEnum.TEXTAREA.code().equals(paperQuestionRel.getQuestionType())){

		}else{
			return ErrorDesc.failureMessage("当前题型不支持");
		}

		//判断当前时间是否到
		PaperTask paperTask= paperTaskService.getById(taskId);
		dao.fill(paperTask).with(PaperTaskMeta.PAPER_RELEASE).execute();
		Date curTime=new Date();
		PaperRelease release=paperTask.getPaperRelease();
		if(PaperTaskResultStatusEnum.ACTING.code().equals(paperTask.getPaperStatus())){
			Calendar calendar=Calendar.getInstance();
			calendar.setTime(paperTask.getStartTime());
			calendar.add(Calendar.MINUTE, paperTask.getPaperRelease().getCost());
			Date endTime=calendar.getTime();
			//考试时间截止
			String format="yyyy-MM-dd HH:mm:ss";
			SimpleDateFormat sdf=new SimpleDateFormat(format);
			if(curTime.after(endTime)){
				return ErrorDesc.failureMessage("当前考试任务时间已结束，结束时间为:"+sdf.format(endTime)+",请提交。").code("100");
			}
			//考试时间截止
			if(curTime.after(release.getEdate())){
				return ErrorDesc.failureMessage("当前考试任务时间已截止，结束时间为:"+sdf.format(release.getSdate())+",请提交。").code("100");
			}

		}else{
			return ErrorDesc.failureMessage("当前状态，不能答题。");
		}



		Rcd rs=dao.queryRecord("select * from hr_paper_question_answer where task_id=? and question_rel_id=?",taskId,questionRelId);
		if(rs==null){
			PaperQuestionAnswer answer=new PaperQuestionAnswer();
			answer.setTaskId(taskId);
			answer.setQuestionRelId(questionRelId);
			answer.setValue(value);
			paperQuestionAnswerService.insert(answer,false);
		}else{
			dao.execute("update hr_paper_question_answer set value=? where id=?",value,rs.getString("id"));
		}
		return ErrorDesc.success();
	}

	/**
	 * 添加，如果语句错误，则抛出异常
	 * @param paper 数据对象
	 * @return 插入是否成功
	 * */
	@Override
	public Result insert(Paper paper) {
		return this.insert(paper,true);
	}

	/**
	 * 批量插入实体，事务内
	 * @param paperList 实体数据清单
	 * @return 插入是否成功
	 * */
	@Override
	public Result insertList(List<Paper> paperList) {
		return super.insertList(paperList);
	}

	
	/**
	 * 按主键删除考试试卷
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdPhysical(String id) {
		Paper paper = new Paper();
		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		paper.setId(id);
		try {
			boolean suc = dao.deleteEntity(paper);
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}
	
	/**
	 * 按主键删除考试试卷
	 *
	 * @param id 主键
	 * @return 删除是否成功
	 */
	public Result deleteByIdLogical(String id) {
		Paper paper = new Paper();
		if(id==null) return ErrorDesc.failure().message("id 不允许为 null 。");
		paper.setId(id);
		paper.setDeleted(true);
		paper.setDeleteBy((String)dao.getDBTreaty().getLoginUserId());
		paper.setDeleteTime(new Date());
		try {
			boolean suc = dao.updateEntity(paper,SaveMode.NOT_NULL_FIELDS);
			return suc?ErrorDesc.success():ErrorDesc.failure();
		}
		catch(Exception e) {
			Result r= ErrorDesc.failure();
			r.extra().setException(e);
			return r;
		}
	}

	/**
	 * 更新，如果执行错误，则抛出异常
	 * @param paper 数据对象
	 * @param mode 保存模式
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(Paper paper , SaveMode mode) {
		return this.update(paper,mode,true);
	}




	/**
	 * 更新，根据 throwsException 参数抛出异常或返回 Result 对象
	 * @param paper 数据对象
	 * @param mode 保存模式
	 * @param throwsException 是否抛出异常，如果不抛出异常，则返回一个失败的 Result 对象
	 * @return 保存是否成功
	 * */
	@Override
	public Result update(Paper paper , SaveMode mode,boolean throwsException) {
		if(PaperQuestionModeEnum.RAND.code().equals(paper.getQuestionMode())){
			//return ErrorDesc.failureMessage("当前【"+PaperQuestionModeEnum.RAND.text()+"】选题模式不支持");
		}
		Result r=super.update(paper , mode , throwsException);
		if(r.isSuccess()){
			renderQuestionContent(paper.getId());
			computeQuestionStatics(paper);
		}
		return r;
	}

	@Override
	public Result computeQuestionStatics(Paper paper){
		String id=paper.getId();
		if(PaperQuestionModeEnum.FIX.code().equals(paper.getQuestionMode())){
			String sql="update hr_paper set \n" +
					"total_score=(select ifnull(sum(score),0) from hr_paper_question_rel where deleted=0 and paper_id=?),\n" +
					"question_r_cnt=(select count(1) from hr_paper_question_rel where deleted=0 and paper_id=?),\n" +
					"judge_r_cnt=(select count(1) from hr_paper_question_rel where deleted=0 and paper_id=? and question_type='judge'),\n" +
					"radio_r_cnt=(select count(1) from hr_paper_question_rel where deleted=0 and paper_id=? and question_type='radio'),\n" +
					"choice_r_cnt=(select count(1) from hr_paper_question_rel where deleted=0 and paper_id=? and question_type='choice'),\n" +
					"textarea_r_cnt=(select count(1) from hr_paper_question_rel where deleted=0 and paper_id=? and question_type='textarea')\n" +
					"where id=?";
			dao.execute(sql,id,id,id,id,id,id,id);
		}else if(PaperQuestionModeEnum.RAND.code().equals(paper.getQuestionMode())){
			//
			String sql="update hr_paper set \n" +
					"total_score=judge_cnt*judge_score+radio_cnt*radio_score+choice_cnt*choice_score+textarea_cnt*textarea_score,\n" +
					"question_r_cnt=judge_cnt+radio_cnt+choice_cnt+textarea_cnt,\n" +
					"judge_r_cnt=judge_cnt,\n" +
					"radio_r_cnt=radio_cnt,\n" +
					"choice_r_cnt=choice_cnt,\n" +
					"textarea_r_cnt=textarea_cnt \n" +
					"where id=?";
			 dao.execute(sql,id);
		}

		return ErrorDesc.success();
	}




	/**
	 * 更新实体集，事务内
	 * @param paperList 数据对象列表
	 * @param mode 保存模式
	 * @return 保存是否成功
	 * */
	@Override
	public Result updateList(List<Paper> paperList , SaveMode mode) {
		return super.updateList(paperList , mode);
	}

	
	/**
	 * 按主键更新考试试卷
	 *
	 * @param id 主键
	 * @return 是否更新成功
	 */
	public boolean update(DBField field,Object value , String id) {
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		if(!field.table().name().equals(this.table())) throw new IllegalArgumentException("更新的数据表["+field.table().name()+"]与服务对应的数据表["+this.table()+"]不一致");
		int suc=dao.update(field.table().name()).set(field.name(), value).where().and("id = ? ",id).top().execute();
		return suc>0;
	}

	
	/**
	 * 按主键获取考试试卷
	 *
	 * @param id 主键
	 * @return Paper 数据对象
	 */
	public Paper getById(String id) {
		Paper sample = new Paper();
		if(id==null) throw new IllegalArgumentException("id 不允许为 null ");
		sample.setId(id);
		return dao.queryEntity(sample);
	}

	/**
	 * 等价于 queryListByIds
	 * */
	@Override
	public List<Paper> getByIds(List<String> ids) {
		return this.queryListByIds(ids);
	}

	@Override
	public List<Paper> queryListByIds(List<String> ids) {
		return super.queryListByUKeys("id",ids);
	}

	@Override
	public Map<String, Paper> queryMapByIds(List<String> ids) {
		return super.queryMapByUKeys("id",ids, Paper::getId);
	}



	/**
	 * 查询实体集合，默认情况下，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @return 查询结果
	 * */
	@Override
	public List<Paper> queryList(PaperVO sample) {
		return super.queryList(sample);
	}


	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<Paper> queryPagedList(PaperVO sample, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, pageSize, pageIndex);
	}

	/**
	 * 分页查询实体集，字符串使用模糊匹配，非字符串使用精确匹配
	 *
	 * @param sample  查询条件
	 * @param condition 其它条件
	 * @param pageSize 分页条数
	 * @param pageIndex 页码
	 * @return 查询结果
	 * */
	@Override
	public PagedList<Paper> queryPagedList(Paper sample, ConditionExpr condition, int pageSize, int pageIndex) {
		return super.queryPagedList(sample, condition, pageSize, pageIndex);
	}

	/**
	 * 检查 实体 是否已经存在 , 判断 主键值不同，但指定字段的值相同的记录是否存在
	 *
	 * @param paper 数据对象
	 * @return 判断结果
	 */
	public Boolean checkExists(Paper paper) {
		//TDOD 此处添加判断段的代码
		//boolean exists=super.checkExists(paper, SYS_ROLE.NAME);
		//return exists;
		return false;
	}

	/**
	 * 批量检查引用
	 * @param ids  检查这些ID是否又被外部表引用
	 * */
	@Override
	public <T> Map<T, ReferCause> hasRefers(List<T> ids) {
		// 默认无业务逻辑，返回此行；有业务逻辑需要校验时，请修改并使用已注释的行代码！！！
		return MapUtil.asMap(ids,new ReferCause(false));
		// return super.hasRefers(FoxnicWeb.BPM_PROCESS_INSTANCE.FORM_DEFINITION_ID,ids);
	}





}